package com.elsa.smart_buffet.utils;

import org.springframework.stereotype.Component;

import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Component
public class DateUtil {

	public static Calendar calendar = null;

	/**
	 * @param dateStr String 字符型日期
	 * @param format  String 格式
	 * @return Date 日期
	 * @throws ParseException
	 * @Description: TODO(格式化日期) <BR>
	 * @author jinyu
	 * @date 2014-3-6 下午04:42:09
	 * @version 1.0
	 */
	public static Date parseDate(String dateStr, String format) {
		try {
			return Date.from(LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern(format)).atZone(ZoneId.systemDefault()).toInstant());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * Description:  比较两个时间的大小，如果第一个参数时间大于第二个，返回true<BR>
	 *
	 * @param _startDate
	 * @param _endDate
	 * @return boolean
	 * @author wen.junhui
	 * @date 2016年3月8日 下午8:12:14
	 */
	public static boolean compareTo(Date _startDate, Date _endDate) {
		long _sTemp = _startDate == null ? 0L : _startDate.getTime();
		long _eTemp = _endDate == null ? 0L : _endDate.getTime();
		return _sTemp - _eTemp > 0L;
	}

	/**
	 * 功能描述：格式化日期
	 *
	 * @param dateStr String 字符型日期：YYYY-MM-DD 格式
	 * @return Date
	 */
	public static Date parseDate(String dateStr) {
		return parseDate(dateStr, "yyyy-MM-dd");
	}

	public static Date simpleParseDate(String dateStr,String format){
		SimpleDateFormat formatter = new SimpleDateFormat( format);
		Date date = null;
		try {
			date = formatter.parse(dateStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}

	/**
	 * 功能描述：格式化输出日期
	 *
	 * @param date   Date 日期
	 * @param format String 格式
	 * @return 返回字符型日期
	 */
	public static String format(Date date, String format) {
		String result = "";
		try {
			if (date != null) {
				result = date.toInstant().atZone(ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern(format));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 功能描述：格式化输出日期
	 *
	 * @param date   Timestamp 日期
	 * @param format String 格式
	 * @return 返回字符型日期
	 */
	public static String format(Timestamp date, String format) {
		String result = "";
		try {
			if (date != null) {
				return date.toLocalDateTime().format(DateTimeFormatter.ofPattern(format));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}


	/**
	 * 功能描述：
	 *
	 * @param date Date 日期
	 * @return
	 */
	public static String format(Date date) {
		return format(date, "yyyy/MM/dd");
	}

	public static String formatDateTime(Date date) {
		return format(date, "yyyy/MM/dd HH:mm:ss");
	}

	/**
	 * 功能描述：返回年份
	 *
	 * @param date Date 日期
	 * @return 返回年份
	 */
	public static int getYear(Date date) {
		calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.YEAR);
	}

	/**
	 * 功能描述：返回月份
	 *
	 * @param date Date 日期
	 * @return 返回月份
	 */
	public static int getMonth(Date date) {
		calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.MONTH) + 1;
	}

	/**
	 * 功能描述：返回日份
	 *
	 * @param date Date 日期
	 * @return 返回日份
	 */
	public static int getDay(Date date) {
		calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 功能描述：返回小时
	 *
	 * @param date 日期
	 * @return 返回小时
	 */
	public static int getHour(Date date) {
		calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.HOUR_OF_DAY);
	}

	/**
	 * 功能描述：返回分钟
	 *
	 * @param date 日期
	 * @return 返回分钟
	 */
	public static int getMinute(Date date) {
		calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.MINUTE);
	}

	/**
	 * 返回秒钟
	 *
	 * @param date Date 日期
	 * @return 返回秒钟
	 */
	public static int getSecond(Date date) {
		calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.SECOND);
	}

	/**
	 * 功能描述：返回毫秒
	 *
	 * @param date 日期
	 * @return 返回毫秒
	 */
	public static long getMillis(Date date) {
		calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.getTimeInMillis();
	}

	/**
	 * 功能描述：返回字符型日期
	 *
	 * @param date 日期
	 * @return 返回字符型日期 yyyy/MM/dd 格式
	 */
	public static String getDate(Date date) {
		return format(date, "yyyy/MM/dd");
	}

	/**
	 * 功能描述：返回字符型时间
	 *
	 * @param date Date 日期
	 * @return 返回字符型时间 HH:mm:ss 格式
	 */
	public static String getTime(Date date) {
		return format(date, "HH:mm:ss");
	}

	/**
	 * 功能描述：返回字符型日期时间
	 *
	 * @param date Date 日期
	 * @return 返回字符型日期时间 yyyy/MM/dd HH:mm:ss 格式
	 */
	public static String getDateTime(Date date) {
		return format(date, "yyyy/MM/dd HH:mm:ss");
	}

	/**
	 * Description: 增加或减少天数 <BR>
	 *
	 * @param date
	 * @param amount 小于0 等于减去
	 * @return
	 * @author yang.wei
	 * @date 2017年11月16日 下午2:13:55
	 */
	public static Date addDay(Date date, int amount) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH, amount);
		return calendar.getTime();
	}

	/**
	 * @param date
	 * @param amount            小于0 等于减去
	 * @param startFromFirstDay 结果值是否从第一天开始，true：从第一天开始，false:从原来的天数开始
	 * @return Date
	 * @throws
	 * @Title: addMonth
	 * @Description:增加或减少月数
	 */
	public static Date addMonth(Date date, int amount, boolean startFromFirstDay) {

		calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, amount);
		date = calendar.getTime();
		String sDate = "";
		if (startFromFirstDay) {
			sDate = DateUtil.format(date, "yyyy-MM") + "-01";
			date = DateUtil.parseDate(sDate, "yyyy-MM-dd");
		}
		return date;
	}

	/**
	 * Description: 增加或减少小时数<BR>
	 *
	 * @param date
	 * @param amount 小于0 等于减去
	 * @return
	 * @author yang.wei
	 * @date 2017年11月16日 下午2:13:55
	 */
	public static Date addHour(Date date, int amount) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.HOUR_OF_DAY, amount);
		return calendar.getTime();
	}

	/**
	 * 功能描述：日期相加
	 *
	 * @param date Date 日期
	 * @param day  int 天数
	 * @return 返回相加后的日期
	 */
	public static Date addDate(Date date, int day) {
		calendar = Calendar.getInstance();
		long millis = getMillis(date) + ((long) day) * 24 * 3600 * 1000;
		calendar.setTimeInMillis(millis);
		return calendar.getTime();
	}

	/**
	 * 功能描述：日期相减
	 *
	 * @param date  Date 日期
	 * @param date1 Date 日期
	 * @return 返回相减后的日期
	 */
	public static int diffDate(Date date, Date date1) {
		return (int) ((getMillis(date) - getMillis(date1)) / (24 * 3600 * 1000));
	}

	/**
	 * 功能描述：取得指定月份的第一天
	 *
	 * @param strdate String 字符型日期
	 * @return String yyyy-MM-dd 格式
	 */
	public static String getMonthBegin(String strdate) {
		return format(parseDate(strdate), "yyyy-MM") + "-01";
	}

	/**
	 * 功能描述：取得指定月份的最后一天
	 *
	 * @param strdate String 字符型日期
	 * @return String 日期字符串 yyyy-MM-dd格式
	 */
	public static String getMonthEnd(String strdate) {
		calendar = Calendar.getInstance();
		calendar.setTime(parseDate(getMonthBegin(strdate)));
		calendar.add(Calendar.MONTH, 1);
		calendar.add(Calendar.DAY_OF_YEAR, -1);
		return formatDate(calendar.getTime());
	}

	/**
	 * 功能描述：常用的格式化日期
	 *
	 * @param date Date 日期
	 * @return String 日期字符串 yyyy-MM-dd格式
	 */
	public static String formatDate(Date date) {
		return formatDateByFormat(date, "yyyy-MM-dd");
	}

	/**
	 * 功能描述：以指定的格式来格式化日期
	 *
	 * @param date   Date 日期
	 * @param format String 格式
	 * @return String 日期字符串
	 */
	public static String formatDateByFormat(Date date, String format) {
		String result = "";
		if (date != null) {
			try {
				result = date.toInstant().atZone(ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern(format));
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}
		return result;
	}

	/**
	 * Description: 返回系统当前时间 <BR>
	 *
	 * @return Date 日期对象
	 * @author jin.yu
	 * @date 2014-4-4 上午11:19:23
	 * @version 1.0
	 */
	public static Date now() {
		Date date = new Date(System.currentTimeMillis());
		return date;
	}

	/**
	 * Description: 以字符串返回系统当前时间，返回格式为：yyyy-MM-dd HH:mm:ss <BR>
	 *
	 * @return String系统当前时间，格式：yyyy-MM-dd HH:mm:ss
	 * @author jin.yu
	 * @date 2014-4-4 上午11:19:18
	 * @version 1.0
	 */
	public static String nowFormat() {
		Date date = new Date(System.currentTimeMillis());
		return format(date, "yyyy-MM-dd HH:mm:ss");
	}

	public static Timestamp nowSqlDate() throws ParseException {

		SimpleDateFormat sp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date du = sp.parse(nowFormat());
		Timestamp st = new Timestamp(du.getTime());
		return st;
	}

	public static Timestamp nowSqlDate(String date) throws ParseException {
		SimpleDateFormat sp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date du = sp.parse(date);
		Timestamp st = new Timestamp(du.getTime());
		return st;

	}

	public static java.sql.Date nowSqlToDate(String date) throws ParseException {

		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Date date1 = format.parse(date);
		return new java.sql.Date((date1.getTime()));

	}

	/**
	 * Description: 取得两个日期之间的日期，返回日期的集合 <BR>
	 *
	 * @param dBegin 开始时间
	 * @param dEnd   结束时间
	 * @return List 日期的集合 日期格式为：yyyy-MM-dd
	 * @author jin.yu
	 * @date 2014-4-11 下午03:37:02
	 * @version 1.0
	 */
	public static List<String> findDates(Date dBegin, Date dEnd) {
		List<String> lDate = new ArrayList<String>();
		lDate.add(formatDate(dBegin));
		Calendar calBegin = Calendar.getInstance();
		// 使用给定的 Date 设置此 Calendar 的时间
		calBegin.setTime(dBegin);
		Calendar calEnd = Calendar.getInstance();
		// 使用给定的 Date 设置此 Calendar 的时间
		calEnd.setTime(dEnd);
		// 测试此日期是否在指定日期之后
		while (dEnd.after(calBegin.getTime())) {
			// 根据日历的规则，为给定的日历字段添加或减去指定的时间量
			calBegin.add(Calendar.DAY_OF_MONTH, 1);
			lDate.add(formatDate(calBegin.getTime()));
		}
		return lDate;
	}

	/**
	 * Description:和当前日期进行比较 <BR>
	 *
	 * @param sDate
	 * @return 比较结果
	 * @author zhangzun
	 * @date 2014-5-4 下午03:14:07
	 * @version 1.0
	 */
	public static int compareNow(String sDate) {
		Date _date = parseDate(sDate);
		Date now = now();
		return _date.compareTo(now);
	}

	/**
	 * Description:  Date类型转成XMLGregorianCalendar类型，用于XML类型的时间格式<BR>
	 *
	 * @param date
	 * @return
	 * @author liu.jian
	 * @date 2016年3月16日 下午3:15:54
	 */
	public static XMLGregorianCalendar convertToXMLGregorianCalendar(Date date) {
		GregorianCalendar cal = new GregorianCalendar();
		cal.setTime(date);
		XMLGregorianCalendar gc = null;
		try {
			gc = DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
		} catch (Exception e) {

			e.printStackTrace();
		}
		return gc;
	}

	/**
	 * Description: XMLGregorianCalendar类型转成Date类型 <BR>
	 *
	 * @param cal
	 * @return
	 * @author liu.jian
	 * @date 2016年3月16日 下午3:17:25
	 */
	public static Date convertToDate(XMLGregorianCalendar cal) {
		GregorianCalendar ca = cal.toGregorianCalendar();
		return ca.getTime();
	}

	/**
	 * Description: 毫秒转换为Date类型 <BR>
	 *
	 * @param mill
	 * @return
	 */
	public static Date formatMill(Long mill) {
		Calendar c = Calendar.getInstance();
		c.setTimeInMillis(mill);
		return c.getTime();
	}

	public static Date asDate(LocalDate localDate) {
		return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
	}

	public static Date asDate(LocalDateTime localDateTime) {
		return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
	}

	public static LocalDate asLocalDate(Date date) {
		return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
	}

	public static LocalDateTime asLocalDateTime(Date date) {
		return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
	}

	/**
	 * 将开始时间和截止时间转换成海贝日期范围字符串
	 *
	 * @param start 开始时间 为空则返回 null
	 * @param end   截止时间 为空则返回 null
	 * @return 海贝日期范围字符串
	 */
	public static String asHybaseDateRange(Date start, Date end) {
		if (start != null && end != null) {
			SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
			return "[" + format.format(start) + " TO " + format.format(end) + "]";
		}
		return null;
	}

	public static String formatRange(Date startDate, Date endDate) {
		if (startDate != null && endDate != null) {
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			return "[" + format.format(startDate) + " 至 " + format.format(endDate) + "]";
		}
		return "";
	}


	/**
	 * 获取当天的起始时间
	 * @return
	 */
	public static Date getStartDate(){
		Calendar instance = Calendar.getInstance();
		instance.set(Calendar.HOUR_OF_DAY,0);
		instance.set(Calendar.MINUTE,0);
		instance.set(Calendar.SECOND,0);
		instance.set(Calendar.MILLISECOND,0);
		return instance.getTime();
	}

	/**
	 * 获取当天的结束时间
	 * @return
	 */
	public static Date getEndDate(){
		Calendar instance = Calendar.getInstance();
		instance.set(Calendar.HOUR_OF_DAY,23);
		instance.set(Calendar.MINUTE,23);
		instance.set(Calendar.SECOND,59);
		instance.set(Calendar.MILLISECOND,999);
		return instance.getTime();
	}

	public static java.sql.Date StringToDate(String sDate) {
		/**
		 *str转date方法
		 */
		String str = sDate;
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		java.util.Date d = null;
		try {
			d = format.parse(str);
		} catch (Exception e) {
			e.printStackTrace();
		}
		java.sql.Date date = new java.sql.Date(d.getTime());
		return date;
	}

}
